package me.zhengjie.modules.supplier_app.rest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.aop.log.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.common.service.TRegionService;
import me.zhengjie.modules.common.service.dto.TRegionQueryCriteria;
import me.zhengjie.modules.customer.service.TCustomerInfoService;
import me.zhengjie.modules.customer.service.dto.TCustomerInfoQueryCriteria;
import me.zhengjie.modules.equipment.domain.TEquipment;
import me.zhengjie.modules.equipment.service.TEquipmentService;
import me.zhengjie.modules.equipment.service.dto.TEquipmentDTO;
import me.zhengjie.modules.monitor.service.RedisService;
import me.zhengjie.modules.security.utils.VerifyCodeUtils;
import me.zhengjie.modules.serviceprovider.domain.TServiceproviderPerson;
import me.zhengjie.modules.serviceprovider.repository.TServiceproviderPersonRepository;
import me.zhengjie.modules.serviceprovider.service.TServiceproviderInfoService;
import me.zhengjie.modules.serviceprovider.service.TServiceproviderPersonService;
import me.zhengjie.modules.serviceprovider.service.dto.TServiceproviderInfoDTO;
import me.zhengjie.modules.serviceprovider.service.dto.TServiceproviderPersonDTO;
import me.zhengjie.modules.system.common.EnumAccidentSource;
import me.zhengjie.modules.system.common.EnumWorkorderStatus;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.DictService;
import me.zhengjie.modules.system.service.dto.DictDTO;
import me.zhengjie.modules.system.service.dto.DictDetailDTO;
import me.zhengjie.modules.workorder.domain.TAccident;
import me.zhengjie.modules.workorder.domain.TWorkOrder;
import me.zhengjie.modules.workorder.domain.TWorkOrderLog;
import me.zhengjie.modules.workorder.service.TAccidentService;
import me.zhengjie.modules.workorder.service.TWorkOrderLogService;
import me.zhengjie.modules.workorder.service.TWorkOrderService;
import me.zhengjie.modules.workorder.service.dto.*;
import me.zhengjie.service.SmsSerivice;
import me.zhengjie.utils.HttpResponseUtils;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.Param;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * Created by bruce on 19/11/15.
 */
@Slf4j
@RestController
@RequestMapping(value = "app/supplier")
public class TAppSupplierController {

    @Autowired
    private TWorkOrderService tWorkOrderService;

    @Autowired
    private TWorkOrderLogService tWorkOrderLogService;

    @Autowired
    private TCustomerInfoService tCustomerInfoService;

    @Autowired
    private TEquipmentService tEquipmentService;

    @Autowired
    private TAccidentService tAccidentService;

    @Autowired
    private DictDetailService dictDetailService;

    @Autowired
    private TEquipmentService equipmentService;

    @Autowired
    private TServiceproviderPersonRepository tServiceproviderPersonRepository;

    @Autowired
    private TServiceproviderPersonService tServiceproviderPersonService;

    @Autowired
    private TRegionService tRegionService;

    @Autowired
    private TServiceproviderInfoService tServiceproviderInfoService;

    @Autowired
    private SmsSerivice smsSerivice;

    @Autowired
    private RedisService redisService;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app查询TWorkOrder")
    @GetMapping(value = "/workorder")
    public ResponseEntity getTWorkOrders(@Nullable  TWorkOrderQueryCriteria criteria, Pageable pageable){
        Long serviceproviderid = SecurityUtils.getOwnerId(); //供应商id
        criteria.setSupplier(serviceproviderid);
        Integer status = criteria.getStatus() ;

        if(status == null) {
            return new ResponseEntity(tWorkOrderService.queryAll(criteria, pageable), HttpStatus.OK);
        } else {
            //获取可接单数据,以及自己处理的其他数据
            if(status.equals(EnumWorkorderStatus.DISPATCHED.getValue())) { //获取可接单数据
                Long enginner = SecurityUtils.getUserId();
                TServiceproviderPersonDTO personDTO  = tServiceproviderPersonService.findById(enginner);
                //获取可接单数据
                ArrayList<String> level = new ArrayList<>();
                String str = personDTO.getLevel();
                if(str != null) {
                    if(str.equals("初级")) {
                        level.add("初级");

                    }
                    if(str.equals("中级")) {
                        level.add("中级");
                        level.add("初级");
                    }
                    if(str.equals("高级")) {
                        level.add("高级");
                        level.add("中级");
                        level.add("初级");
                    }
                }else{
                    level.add("初级");
                    level.add("中级");
                    level.add("高级");
                }
                return new ResponseEntity( tWorkOrderService.queryAcceptableWorkOrder(personDTO.getMajor(), level,
                        personDTO.getCountry(), personDTO.getProvince(), personDTO.getCity(), personDTO.getCounty(),
                        serviceproviderid,pageable), HttpStatus.OK);
            } else {

                TWorkOrderQueryCriteriaEx criteriaEx = new TWorkOrderQueryCriteriaEx();
                BeanUtils.copyProperties(criteria, criteriaEx, "status");
                List<Integer> statusEx = new ArrayList<>();
                statusEx.add(status);
                if (status.equals(EnumWorkorderStatus.ARRIVED.getValue()))
                    statusEx.add(EnumWorkorderStatus.PROCESSING.getValue());
                if (status.equals(EnumWorkorderStatus.PROCESSING.getValue()))
                    statusEx.add(EnumWorkorderStatus.ARRIVED.getValue());
                if (status.equals(EnumWorkorderStatus.FINISHED.getValue())) {
                    statusEx.add(EnumWorkorderStatus.EVAlUATED.getValue());  //评价
                    statusEx.add(EnumWorkorderStatus.CLOSED.getValue());  //结束
                }
                if (status.equals(EnumWorkorderStatus.EVAlUATED.getValue())) {
                    statusEx.add(EnumWorkorderStatus.FINISHED.getValue());    //结单
                    statusEx.add(EnumWorkorderStatus.CLOSED.getValue());   //关闭

                }
                criteriaEx.setStatus(statusEx);

                if (status > EnumWorkorderStatus.DISPATCHED.getValue()) { //已结单后,只能获取自己的工单
                    criteriaEx.setEngineer(SecurityUtils.getUserId()); //工程师id
                }
                return new ResponseEntity(tWorkOrderService.queryAll(criteriaEx, pageable), HttpStatus.OK);
            }
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app查询TWorkOrder")
    @GetMapping(value = "/workorderlog")
    public ResponseEntity getTWorkOrderLogs(@Nullable TWorkOrderLogQueryCriteria criteria, Pageable pageable){
        return new ResponseEntity(tWorkOrderLogService.queryAll(criteria,pageable), HttpStatus.OK);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app工程师回单处理")
    @PostMapping(value = "/orderprocess")
    //@PreAuthorize("hasAnyRole('ADMIN','TWORKORDERLOG_ALL','TWORKORDERLOG_CREATE')")
    public ResponseEntity orderProcess(@RequestBody TWorkOrderLog resources){
        resources.setOperator(SecurityUtils.getName());
        resources.setOrderStatus(500); //TODO状态操作,回单
        return new ResponseEntity(tWorkOrderLogService.create(resources),HttpStatus.CREATED);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app查询工单状态统计值")
    @GetMapping(value = "/workorderbystatus")
    public ResponseEntity getWorkOrderAggByStatus() {
        Long serviceproviderid = SecurityUtils.getOwnerId() ;
        Long enginner = SecurityUtils.getUserId();
        TServiceproviderPersonDTO personDTO  = tServiceproviderPersonService.findById(enginner);

        HashMap<Integer, Long> statics = new HashMap<Integer,Long>();

        //获取可接单数据
        ArrayList<String> level = new ArrayList<>();
        String str = personDTO.getLevel();
        if(str != null) {
            if(str.equals("初级")) {
                level.add("初级");

            }
            if(str.equals("中级")) {
                level.add("中级");
                level.add("初级");
            }
            if(str.equals("高级")) {
                level.add("高级");
                level.add("中级");
                level.add("初级");
            }
        }else{
            level.add("初级");
            level.add("中级");
            level.add("高级");
        }
        Long acceptable = tWorkOrderService.countAcceptableWorkOrder(personDTO.getMajor(), level,
                personDTO.getCountry(), personDTO.getProvince(), personDTO.getCity(), personDTO.getCounty(),
                serviceproviderid);
        statics.put(EnumWorkorderStatus.DISPATCHED.getValue(), acceptable);

        //根据供应商\工程师获取已处理工单
        List<?> list = tWorkOrderService.getWorkOrderAggByStatus(serviceproviderid, SecurityUtils.getUserId());
        for(Object _row: list) {
            Object[] row = (Object[])_row;
            Integer status = (Integer)row[1];

            //status.intValue() == EnumWorkorderStatus.DISPATCHED.getValue() 已派单,过滤条件不一样,
            if( status.intValue()==EnumWorkorderStatus.ACCEPTED.getValue()
                    || status.intValue() == EnumWorkorderStatus.ARRIVED.getValue()
                    || status.intValue() == EnumWorkorderStatus.PROCESSING.getValue()
                    || status.intValue() == EnumWorkorderStatus.FINISHED.getValue()
                    || status.intValue() == EnumWorkorderStatus.EVAlUATED.getValue()
                    || status.intValue() == EnumWorkorderStatus.CLOSED.getValue()) {
                Long count = statics.getOrDefault(status,0L);
                //已到场,处理中
                if(status.intValue()==EnumWorkorderStatus.PROCESSING.getValue()
                        || status.intValue()==EnumWorkorderStatus.ARRIVED.getValue()) {
                    statics.put(EnumWorkorderStatus.ARRIVED.getValue(),count+(Long)row[0]);
                }else if(status.intValue()==EnumWorkorderStatus.FINISHED.getValue()
                        || status.intValue()==EnumWorkorderStatus.EVAlUATED.getValue()
                        || status.intValue()==EnumWorkorderStatus.CLOSED.getValue() ){
                    //结单,已评价
                    statics.put(EnumWorkorderStatus.FINISHED.getValue(),count+(Long)row[0]);
                    statics.put(EnumWorkorderStatus.EVAlUATED.getValue(),count+(Long)row[0]);
                    statics.put(EnumWorkorderStatus.CLOSED.getValue(),count+(Long)row[0]);
                }else{
                    statics.put(status,(Long)row[0]);
                }
            }
        }
        JSONArray array = new JSONArray();
        for(HashMap.Entry<Integer,Long> item: statics.entrySet()) {
            JSONObject object = new JSONObject();
            object.put("count",item.getValue());
            object.put("status",item.getKey());
            array.add(object);
        }

        return new ResponseEntity(array, HttpStatus.OK);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app查询客户信息")
    @GetMapping(value = "/customerinfo")
    public ResponseEntity searchCustomerInfo(
            @RequestParam(value = "code",required = false)String code) {
        if(StringUtils.isEmpty(code))
            return new ResponseEntity(HttpStatus.OK);
        else
            return new ResponseEntity(tCustomerInfoService.queryByCodeOrName(code),HttpStatus.OK);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app查询设备信息")
    @GetMapping(value = "/equipmentinfo")
    public ResponseEntity searchCustomerEqtInfo(
            @RequestParam(value = "code",required = false)String code,
            @RequestParam(value="customerId", required = false) Integer customerId) {
        if(StringUtils.isEmpty(code))
            return new ResponseEntity(HttpStatus.OK);
        else
            //TODO 增加客户标识条件
            return new ResponseEntity(tEquipmentService.queryByCodeOrName(code),HttpStatus.OK);
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app代客报修")
    @PostMapping(value = "/addAccident")
    public ResponseEntity create(@Validated @RequestBody TAccident resources){
        try {
            Optional<TServiceproviderPerson> supplierOptional = tServiceproviderPersonRepository.findById(SecurityUtils.getUserId());
            TServiceproviderPerson supplier = supplierOptional.get();

            resources.setSource(EnumAccidentSource.SUPPLIER.getValue()); //客户代报
            resources.setInputOperator(supplier.getPersonName());
            resources.setInputTime(new Date());
            resources.setReportTime(new Date()); //上报时间

            TAccidentDTO dto = tAccidentService.createBySupplier(resources,supplier);
            return new ResponseEntity(dto, HttpStatus.OK);
        }catch(Exception ex) {
            ex.printStackTrace();
            return HttpResponseUtils.passDefaultResponse(ex.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("app工单处理")
    @PostMapping(value = "/workorderprocess")
    public ResponseEntity process(@Validated @RequestBody TWorkOrderLog log){
        try {
            tWorkOrderLogService.process(log);
            return HttpResponseUtils.passDefaultResponse("",HttpStatus.OK);
        }catch(Exception ex){
            ex.printStackTrace();
            return HttpResponseUtils.passDefaultResponse(ex.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("获取字典串值")
    @GetMapping(value = "/dictdetail")
    public ResponseEntity getDictDetailValue(@Validated @RequestParam(value = "id") Long id){
        DictDetailDTO dto = dictDetailService.findById(id);
        return new ResponseEntity( dto, HttpStatus.OK);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("获取设备名称")
    @GetMapping(value = "/devicenames")
    public ResponseEntity getDeviceNames(@Validated @RequestParam(value = "id") String id){
        String[] ids = id.split(",");
        if(ids.length == 0) {
            return new ResponseEntity( "", HttpStatus.OK);
        } else {
            Set<String> deviceNames = new HashSet<>();
            for(String _id: ids) {
                TEquipmentDTO equipment = equipmentService.findById(Integer.valueOf(_id));
                if(equipment != null)
                    deviceNames.add(equipment.getEqptname());
            }
            JSONObject obj = new JSONObject();
            obj.put("value",String.join(",",deviceNames.toArray(new String[0])));
            return new ResponseEntity( obj, HttpStatus.OK);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Log("获取个人信息")
    @GetMapping(value = "/userinfo")
    public ResponseEntity getUserInfo(){
        try{
            Long id = SecurityUtils.getUserId();
            TServiceproviderPersonDTO personDTO = tServiceproviderPersonService.findById(id);
            return new ResponseEntity( personDTO, HttpStatus.OK);
        }catch (Exception ex) {
            ex.printStackTrace();
            return HttpResponseUtils.passDefaultResponse(ex);
        }
    }

    @Log("查询TRegion")
    @GetMapping(value = "/tRegion")
    public ResponseEntity getTRegions(TRegionQueryCriteria criteria, Pageable pageable){
        return new ResponseEntity(tRegionService.queryAll(criteria,pageable),HttpStatus.OK);
    }


    @Log("根据邀请码查询企业信息")
    @GetMapping(value = "/byInviteCode")
    public ResponseEntity getProviderInfoByInviteCode(@RequestParam(value = "inviteCode",required = true)String inviteCode){
        try{
            TServiceproviderInfoDTO dto = tServiceproviderInfoService.findByInviteCode(inviteCode);
            JSONObject obj = new JSONObject();
            obj.put("id", dto.getId());
            obj.put("seproName",dto.getSeproName());
            return new ResponseEntity(obj,HttpStatus.OK);
        }catch(Exception ex){
            return HttpResponseUtils.passDefaultResponse("找不到对应企业",HttpStatus.BAD_REQUEST);
        }
    }


    @Log("获取短信验证码")
    @GetMapping(value = "/captcha")
    //@PreAuthorize("hasAnyRole('ADMIN','TSERVICEPROVIDERPERSON_ALL','TSERVICEPROVIDERPERSON_SELECT')")
    public ResponseEntity getSms(@RequestParam String cellphone) {
        String num = VerifyCodeUtils.generateRandomNum(4);
        if (smsSerivice.sendSms(cellphone, num)) {
            redisService.ttl("sms_" + cellphone, num, 60 * 5);  //设置值,有效期60*5秒
            return HttpResponseUtils.passDefaultResponse("OK", HttpStatus.OK);
        } else {
            return HttpResponseUtils.passDefaultResponse("发送验证码失败", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Log("注册工程师")
    @PostMapping(value = "/register")
    //@PreAuthorize("hasAnyRole('ADMIN','TSERVICEPROVIDERPERSON_ALL','TSERVICEPROVIDERPERSON_CREATE')")
    public ResponseEntity register(@RequestBody JSONObject resources) {
        return new ResponseEntity(tServiceproviderPersonService.register(resources), HttpStatus.OK);
    }

    @Log("修改工程师密码")
    @PostMapping(value = "/resetpassword")
    //@PreAuthorize("hasAnyRole('ADMIN','TSERVICEPROVIDERPERSON_ALL','TSERVICEPROVIDERPERSON_CREATE')")
    public ResponseEntity resetpassword(@RequestBody JSONObject resources) {
        return new ResponseEntity(tServiceproviderPersonService.resetpassword(resources), HttpStatus.OK);
    }


    @Log("重新绑定手机")
    @PostMapping(value = "/rebind")
    //@PreAuthorize("hasAnyRole('ADMIN','TSERVICEPROVIDERPERSON_ALL','TSERVICEPROVIDERPERSON_CREATE')")
    public ResponseEntity rebind(@RequestBody JSONObject resources) {
        resources.put("id", SecurityUtils.getUserId());
        return new ResponseEntity(tServiceproviderPersonService.rebind(resources), HttpStatus.OK);
    }
}
